﻿using System.Runtime.CompilerServices;

namespace Two
{
    internal class Program
    {
        public enum GameState
        { 
            Begin,
            OnGoing,
            End
        }

        public enum E_Grid_Type
        {
            Normal,
            Boom,
            Pause,
            Tunnel
        }

        static void Main(string[] args)
        {
            int w = 50;
            int h = 30;
            //初始化窗口
            ConsoleInit(w,h);

            GameState stateId = GameState.Begin;

            //页面选择
            while (true)
            {
                Console.Clear();
                switch (stateId)
                {
                    case GameState.Begin:
                        MainInterface(w, h, ref stateId);
                        break;
                    case GameState.OnGoing:
                        GameScene(w, h, ref stateId);
                        break;
                    case GameState.End:
                        MainInterface(w, h, ref stateId);
                        break;
                    default:break;
                }
                
            }



            Console.Read();
        }

        public static void ConsoleInit(int w, int h)
        {
            Console.CursorVisible = false;
            Console.SetWindowSize(w,h);
            Console.SetBufferSize(w,h);
        }

        public static void MainInterface(int w,int h,ref GameState stateId)
        {
            Console.ForegroundColor = ConsoleColor.White;

            int soq = 0;
            bool changeInterface = false;

            Console.SetCursorPosition(stateId==GameState.Begin?w / 2 - 3:w/2-4, 2);
            Console.Write(stateId == GameState.Begin ? "飞行棋":"游戏结束");

            while (true)
            {
                if (changeInterface) break;

                Console.SetCursorPosition(stateId == GameState.Begin ? w / 2 - 4: w / 2 - 5, 5);
                Console.ForegroundColor = soq == 0 ? ConsoleColor.Red : ConsoleColor.White;
                Console.Write(stateId == GameState.Begin ?"开始游戏":"回到主界面");

                Console.SetCursorPosition(w / 2 - 4, 7);
                Console.ForegroundColor = soq == 1 ? ConsoleColor.Red : ConsoleColor.White;
                Console.Write("结束游戏");

                switch (Console.ReadKey(true).Key)
                {
                    case ConsoleKey.W:
                        soq--;
                        soq = Math.Max(0, soq);
                        break;
                    case ConsoleKey.S:
                        soq++;
                        soq = Math.Min(soq, 1);
                        break;
                    case ConsoleKey.J:
                        if (soq == 0)
                        {
                            stateId = stateId == GameState.Begin ?GameState.OnGoing:GameState.Begin;
                            changeInterface = true;
                        }
                        else
                        {
                            Environment.Exit(0);
                        }
                        break;
                    default: break;
                }
            }

        }

        public static void GameScene(int w,int h, ref GameState stateId)
        {
            //渲染红墙
            DrawRedWall(w, h);

            //绘制地图
            Map map = new Map(14, 3, 90);
            map.RenderMap();

            //绘制人物
            Entity player = new Entity(E_Player.Player, 0);
            Entity Enemy = new Entity(E_Player.Enemy, 0);

            DrawEntity(player, Enemy, map);

            while (true)
            {
                if (RandomMove(w, h, ref player,ref Enemy, map))
                {
                    stateId = GameState.End;
                    break;
                }

                if (RandomMove(w, h,ref Enemy,ref player, map))
                {
                    stateId = GameState.End;
                    break;
                }
            }
        }

        public static void ClearInfo(int h)
        {
            Console.SetCursorPosition(2, h - 5);
            Console.Write("                                     ");
            Console.SetCursorPosition(2, h - 4);
            Console.Write("                                     ");
            Console.SetCursorPosition(2, h - 3);
            Console.Write("                                     ");
            Console.SetCursorPosition(2, h - 2);
            Console.Write("                                     ");
        }


        public static bool RandomMove(int w,int h,ref Entity p,ref Entity otherP,Map map)
        {
            Console.ReadKey(true);

            ClearInfo(h);

            if (p.isPause)
            {
                Console.SetCursorPosition(2, h - 5);
                Console.Write("{0}需在此地暂停一回合", p.type == E_Player.Player ? "玩家" : "电脑");
                p.isPause = false;
                Console.SetCursorPosition(2, h - 4);
                Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ? "电脑" : "玩家");
                return false;
            }

            Random r = new Random();
            int move = r.Next(1, 7);
            p.index = Math.Min(p.index + move, map.GetLength()-1);

            Console.ForegroundColor = p.type == E_Player.Player ? ConsoleColor.Cyan : ConsoleColor.Magenta;

            Console.SetCursorPosition(2,h-5);
            Console.Write("{0}扔出的点数为{1}", p.type == E_Player.Player ? "玩家" : "电脑",move);

            if (p.index == map.GetLength()-1)
            {
                Console.SetCursorPosition(2, h - 4);
                if (p.type == E_Player.Player)
                {
                    Console.Write("恭喜玩家率先抵达终点");
                }
                else
                {
                    Console.Write("很遗憾，电脑先你一步到达终点");
                }

                map.RenderMap();
                DrawEntity(p, otherP, map);

                Console.ForegroundColor = p.type == E_Player.Player ? ConsoleColor.Cyan : ConsoleColor.Magenta;
                Console.SetCursorPosition(2, h - 3);
                Console.Write("按任意键退出");
                Console.ReadKey(true);
                return true;
            }

            E_Grid_Type gridInfo = map.GetGridInfo(p.index);

            switch(gridInfo)
            {
                case E_Grid_Type.Normal:
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}到达一个安全地点", p.type == E_Player.Player ? "你" : "电脑");
                    
                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ?"电脑": "玩家");
                    break;
                case E_Grid_Type.Boom:

                    p.index = Math.Max(0, p.index - 5);

                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}踩到一个炸弹，回退5格子", p.type == E_Player.Player ? "你" : "电脑");

                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ? "电脑" : "玩家");
                    break;

                case E_Grid_Type.Pause:

                    p.isPause = true;

                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}到达一个暂停点,在此地暂停一回合", p.type == E_Player.Player ? "你" : "电脑");

                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ? "电脑" : "玩家");
                    break;

                case E_Grid_Type.Tunnel:
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}到达时空隧道,随机获得效果", p.type == E_Player.Player ? "你" : "电脑");

                    int function = r.Next(1, 91);

                    if (function < 60)
                    {
                        p.index = Math.Max(0, p.index - 5);

                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("{0}回退5格子", p.type == E_Player.Player ? "你" : "电脑");

                        Console.SetCursorPosition(2, h - 2);
                        Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ? "电脑" : "玩家");

                    }
                    else if (function < 80)
                    {
                        p.isPause = true;

                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("{0}需要暂停一回合", p.type == E_Player.Player ? "你" : "电脑");

                        Console.SetCursorPosition(2, h - 2);
                        Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ? "电脑" : "玩家");
                    }
                    else
                    {
                        int t = p.index;
                        p.index = otherP.index;
                        otherP.index = t;

                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("惊喜，惊喜，双方交换位置", p.type == E_Player.Player ? "你" : "电脑");

                        Console.SetCursorPosition(2, h - 2);
                        Console.Write("按任意键，让{0}扔色子", p.type == E_Player.Player ? "电脑" : "玩家");
                    }
                    break;
                default:break;
            }

            map.RenderMap();
            DrawEntity(p, otherP, map);

            return false;
        }

        public static void DrawEntity(Entity player,Entity Enemy,Map map)
        {
            if (player.index == Enemy.index)
            {
                Vector2 pos = map.GetPos(player.index);
                Console.SetCursorPosition(pos.x, pos.y);
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.Write("⊙");
            }
            else
            {
                player.Draw(map);
                Enemy.Draw(map);
            }
        }

        public static void DrawRedWall(int w,int h)
        {
            for (int i = 0; i < w; i += 2)
            {
                Console.SetCursorPosition(i, 0);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("■");

                Console.SetCursorPosition(i, h-1);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("■");

                Console.SetCursorPosition(i, h-6);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("■");

                Console.SetCursorPosition(i, h-11);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("■");
            }

            for (int i = 0; i < h; i += 1)
            {
                Console.SetCursorPosition(0, i);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("■");

                Console.SetCursorPosition(w-2, i);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("■");
            }

            Console.ForegroundColor = ConsoleColor.White;
            Console.SetCursorPosition(2, h - 10);
            Console.Write("□：普通格子");

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.SetCursorPosition(2, h - 9);
            Console.Write("║ ：暂停，一回合不动");

            Console.ForegroundColor = ConsoleColor.Red;
            Console.SetCursorPosition(26, h - 9);
            Console.Write("●：炸弹，倒退5格");

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.SetCursorPosition(2, h - 8);
            Console.Write("¤：时空隧道,随机倒退,暂停,换位置");

            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.SetCursorPosition(2, h - 7);
            Console.Write("★：玩家");

            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.SetCursorPosition(12, h - 7);
            Console.Write("▲：电脑");

            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.SetCursorPosition(22, h - 7);
            Console.Write("⊙：玩家和电脑重合");

            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.SetCursorPosition(22, h - 7);
            Console.Write("⊙：玩家和电脑重合");

            Console.ForegroundColor = ConsoleColor.White;
            Console.SetCursorPosition(2, h - 5);
            Console.Write("按任意键开始扔色子");
        }

        #region 格子结构体
        public struct Vector2
        {
            public int x;
            public int y;

            public Vector2(int x, int y)
            {
                this.x = x; 
                this.y = y;
            }
        }

        public struct Grid
        {
            public E_Grid_Type type;
            public Vector2 pos;

            public Grid(E_Grid_Type type,int x,int y)
            { 
                this.type = type;
                pos = new Vector2(x,y);
            }

            public void Draw()
            {
                Console.SetCursorPosition(pos.x, pos.y);
                switch (type)
                {
                    case E_Grid_Type.Normal:
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("□");
                        break;
                    case E_Grid_Type.Boom:
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write("●");
                        break;
                    case E_Grid_Type.Pause:
                        Console.ForegroundColor = ConsoleColor.Blue;
                        Console.Write("║ ");
                        break;
                    case E_Grid_Type.Tunnel:
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.Write("¤");
                        break;
                    default: break;
                }
            }
        }
        #endregion

        #region 地图结构体
        public struct Map
        {
            Grid[] maps;

            public Map(int sx, int sy, int num)
            { 
                maps = new Grid[num];
                int x = sx;
                int y = sy;

                int indexX = 0;
                int indexY = 0;
                int step = 2;
                
                for (int i = 0; i < num; i++)
                {
                    E_Grid_Type gtype;
                    Random r = new Random();
                    int t = r.Next(0, 101);
                    if (t < 85 || i == 0 || i == num - 1)
                    {
                        gtype = E_Grid_Type.Normal;
                    }
                    else if (t < 90)
                    {
                        gtype = E_Grid_Type.Boom;
                    }
                    else if (t < 95)
                    {
                        gtype = E_Grid_Type.Pause;
                    }
                    else
                    {
                        gtype = E_Grid_Type.Tunnel;
                    }

                    maps[i] = new Grid(gtype, x, y);

                    //计算下一个格子出现的位置
                    if (indexX == 10)
                    {
                        indexY++;
                        y++;
                        if (indexY == 2)
                        {
                            indexX = 0;
                            indexY = 0;
                            step = -step;
                        }
                    }
                    else
                    {
                        indexX++;
                        x += step;
                    }
                }
            }

            public void RenderMap()
            {
                for (int i = 0; i < maps.Length; i++)
                {
                    maps[i].Draw();
                }
            }

            public Vector2 GetPos(int index)
            {
                return maps[index].pos;
            }

            public int GetLength()
            {
                return maps.Length;
            }

            public E_Grid_Type GetGridInfo(int index)
            {
                return maps[index].type;
            }
        }
        #endregion

        #region 人物结构体
        public enum E_Player
        { 
            Player,
            Enemy
        }

        public struct Entity
        {
            public E_Player type;
            public int index;
            public bool isPause = false;


            public Entity(E_Player type, int index)
            {
                this.type = type;
                this.index = index;
            }

            public void Draw(Map map)
            {
                Vector2 pos = map.GetPos(index);
                Console.SetCursorPosition(pos.x, pos.y);
                switch (type)
                {
                    case E_Player.Player:
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write("★");
                        break;
                    case E_Player.Enemy:
                        Console.ForegroundColor = ConsoleColor.Magenta;
                        Console.Write("▲");
                        break;
                    default:break;
                }
            }
        }
        #endregion

    }
}
